package com.base.invoke.utils;

import com.base.invoke.constants.CommConstants;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期时间转换计算操作工具类
 * @author coolpig
 * @date 2019-09-27
 */
public class DateUtils {

    /**
     * 获取当天0点时间戳
     * @return
     */
    private static Long dayTimeInMillis() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取当月0点时间戳
     * @return
     */
    private static Long monthTimeInMillis() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 获取当年0点时间戳
     * @return
     */
    private static Long yearTimeInMillis() {
        Calendar calendar = Calendar.getInstance();// 获取当前日期
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        return time;
    }

    /**
     * 将时间转换为时间戳
     * @param s
     * @return
     * @throws ParseException
     */
    public static String dateToStamp(String s) throws ParseException {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(s);
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /**
     * 将时间戳转换为时间
     * @param s
     * @return
     */
    public static String stampToDate(String s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 将Long类型的时间戳转换成String 类型的时间格式，时间格式为：yyyy-MM-dd HH:mm:ss
     * @param time
     * @return
     */
    public static String convertTimeToString(Long time, String fmt){
        DateTimeFormatter ftf = DateTimeFormatter.ofPattern(fmt);
        return ftf.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
    }

    /**
     * 获取当年第一天0点
     * @return
     */
    public static String getCurrYearFirstDay(){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//要转换的时间格式
        Long firstDayOfYear = yearTimeInMillis();
        return sdf.format(firstDayOfYear);
    }

    /**
     * 字符串转日期
     * @param strDate
     * @param fmt
     * @return
     */
    public static Date strToDate(String strDate, String fmt){
        SimpleDateFormat df = new SimpleDateFormat(fmt);
        Date targetDate = null;
        try {
            targetDate = df.parse(strDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return targetDate;
    }

    /**
     * Date 类型转化为 Long 类型
     * @param date
     * @return
     */
    public static Long dateToLong(Date date){
        return date.getTime();
    }

    /**
     * Long时间戳转Date
     * @param resTime
     * @return
     */
    public static Date longToDate(Long resTime){
        return new Date(resTime);
    }

    /**
     * @Description: 比较两个日期大小
     * @param before
     * @param after
     * @return -1前者小于后者 0前者等于后者 1前者大于后者
     */
    public static int compareTowDays(Date before, Date after) {
        try {
            if (before.getTime() > after.getTime()) {
                return 1;
            } else if (before.getTime() < after.getTime()) {
                return -1;
            } else {
                return 0;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return 0;
    }

    /**
     * 获取四个月(1+3)之前月的最后一天
     * @return
     */
    public static Date getBeforeMothLastDay(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -3);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        Date d = calendar.getTime();
        return d;
    }

    /**
     * 获取两个日期相差几个月
     * @param start
     * @param end
     * @return
     */
    public static int getDifferMonth(Date start, Date end) {
        if (start.after(end)) {
            Date t = start;
            start = end;
            end = t;
        }
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(start);
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(end);
        Calendar temp = Calendar.getInstance();
        temp.setTime(end);
        temp.add(Calendar.DATE, 1);
        int year = endCalendar.get(Calendar.YEAR) - startCalendar.get(Calendar.YEAR);
        int month = endCalendar.get(Calendar.MONTH) - startCalendar.get(Calendar.MONTH);
        if ((startCalendar.get(Calendar.DATE) == 1) && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month + 1;
        } else if ((startCalendar.get(Calendar.DATE) != 1) && (temp.get(Calendar.DATE) == 1)) {
            return year * 12 + month;
        } else if ((startCalendar.get(Calendar.DATE) == 1) && (temp.get(Calendar.DATE) != 1)) {
            return year * 12 + month;
        } else {
            return (year * 12 + month - 1) < 0 ? 0 : (year * 12 + month);
        }
    }

    /**
     * 判断两个日期是否为同年同月
     * @param date1
     * @param date2
     * @return
     */
    public static boolean compareSameYearMonth(Date date1, Date date2) {

        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
//        int year1 = calendar1.get(Calendar.YEAR);
//        int year2 = calendar2.get(Calendar.YEAR);
//        int month1 = calendar1.get(Calendar.MONTH) + 1;
//        int month2 = calendar2.get(Calendar.MONTH) + 1;
//        System.out.println(year1 + "  " + month1);
//        System.out.println(year2 + "  " + month2);
        return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);

    }

    /**
     * 日期格式的计算
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate,Date bdate) throws ParseException
    {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        smdate=sdf.parse(sdf.format(smdate));
        bdate=sdf.parse(sdf.format(bdate));
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     *字符串的日期格式的计算
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(String smdate,String bdate) throws ParseException{
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days=(time2-time1)/(1000*3600*24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 测试用
     */
    public static void getDevicesStatistic() {
        Long time1 = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//要转换的时间格式
        Long time2 = dayTimeInMillis();
        Long time3 = monthTimeInMillis();
        Long time4 = yearTimeInMillis();

        System.out.println("time1: "+sdf.format(time1)+" "+time1);
        System.out.println("time2: "+sdf.format(time2)+" "+time2);
        System.out.println("time3: "+sdf.format(time3)+" "+time3);
        System.out.println("time4: "+sdf.format(time4)+" "+time4);
        // System.out.println("time5: "+sdf.format(1551431981748L));
    }

    /**
     * TEST
     * @param args
     * @throws ParseException
     */
    public static void main(String[] args) throws ParseException {
        //定义时间格式年月日 时分秒
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1=sdf.parse("2019-09-15 00:00:00");
        Date d2=sdf.parse("2019-10-25 00:00:00");
        //方法一：日期格式的计算
        System.out.println(daysBetween(d1,d2));
        //方法二：字符串的日期格式的计算
        System.out.println(daysBetween("2019-09-15 00:00:00","2019-10-25 00:00:00"));


//          new DateUtils().getDevicesStatistic();
//        System.out.println(getCurrYearFirstDay());
//        System.out.println(new Date().getTime());
//        String startTime = "1546272000000";
//        String endTime = "1565070583000";
//        System.out.println("start time ===>>>" + new Date(Long.valueOf(startTime)));
//        System.out.println("end time ===>>>" + new Date(Long.valueOf(endTime)));
//        String s = convertTimeToString(Long.valueOf(startTime), DateUtil.FORMART_FORMART_SHORT_DATE);
//        System.out.println("s============>>>>>" + s);
//        System.out.println(getBeforeMothLastDay());
//        System.out.println(compareTowDays(new Date(), getBeforeMothLastDay()));
//        System.out.println(longToDate(1567404015000l));
//        System.out.println(strToDate("2019-06-01 00:00:00", DateUtil.FORMART_FORMART_LANG_DATE));
        Date d = strToDate("2019-09-30 00:00:00", CommConstants.FORMART_LANG_DATE);
        Date dd = strToDate("2019-09-01 23:59:59", CommConstants.FORMART_LANG_DATE);
//        System.out.println(d);
//        System.out.println(compareTowDays(d, getBeforeMothLastDay()));
//        System.out.println(getDifferMonth(d, dd));
        System.out.println(compareSameYearMonth(d, dd));
    }
}
